static void update_curr_fcfs(struct rq *rq)
{
	struct task_struct *curr = rq->curr;
	u64 delta_exec;

	delta_exec = rq->clock - curr->se.exec_stafcfs;
	if (unlikely((s64)delta_exec < 0))
		delta_exec = 0;

	schedstat_set(curr->se.exec_max, max(curr->se.exec_max, delta_exec));

	curr->se.sum_exec_runtime += delta_exec;
	curr->se.exec_stafcfs = rq->clock;
	cpuacct_charge(curr, delta_exec);
}

static void enqueue_task_fcfs(struct rq *rq, struct task_struct *p, int wakeup)
{
	struct fcfs_prio_array *array = &rq->fcfs.active;

	list_add_tail(&p->run_list, array->queue + p->prio);
	__set_bit(p->prio, array->bitmap);
}

/*
 * Adding/removing a task to/from a priority array:
 */
static void dequeue_task_fcfs(struct rq *rq, struct task_struct *p, int sleep)
{
	struct fcfs_prio_array *array = &rq->fcfs.active;

	update_curr_fcfs(rq);

	list_del(&p->run_list);
	if (list_empty(array->queue + p->prio))
		__clear_bit(p->prio, array->bitmap);
}

/*
 * Put task to the end of the run list without the overhead of dequeue
 * followed by enqueue.
 */
static void requeue_task_fcfs(struct rq *rq, struct task_struct *p)
{
	struct fcfs_prio_array *array = &rq->fcfs.active;

	list_move_tail(&p->run_list, array->queue + p->prio);
}

static void
yield_task_fcfs(struct rq *rq)
{
	requeue_task_fcfs(rq, rq->curr);
}

/*
 * Preempt the current task with a newly woken task if needed:
 */
static void check_preempt_curr_fcfs(struct rq *rq, struct task_struct *p)
{
	if (p->prio < rq->curr->prio)
		resched_task(rq->curr);
}

static struct task_struct *pick_next_task_fcfs(struct rq *rq)
{
	struct fcfs_prio_array *array = &rq->fcfs.active;
	struct task_struct *next;
	struct list_head *queue;
	int idx;

	idx = sched_find_first_bit(array->bitmap);
	if (idx >= MAX_RT_PRIO)
		return NULL;

	queue = array->queue + idx;
	next = list_entry(queue->next, struct task_struct, run_list);

	next->se.exec_stafcfs = rq->clock;

	return next;
}

static void put_prev_task_fcfs(struct rq *rq, struct task_struct *p)
{
	update_curr_fcfs(rq);
	p->se.exec_stafcfs = 0;
}

static void task_tick_fcfs(struct rq *rq, struct task_struct *p)
{
	update_curr_fcfs(rq);
}

static void set_curr_task_fcfs(struct rq *rq)
{
	struct task_struct *p = rq->curr;

	p->se.exec_start = rq->clock;
}

const struct sched_class fcfs_sched_class = {
	.next			= &idle_sched_class,
	.enqueue_task		= enqueue_task_fcfs,
	.dequeue_task		= dequeue_task_fcfs,
	.yield_task		= yield_task_fcfs,

	.check_preempt_curr	= check_preempt_curr_fcfs,

	.pick_next_task		= pick_next_task_fcfs,
	.put_prev_task		= put_prev_task_fcfs,

	.set_curr_task          = set_curr_task_fcfs,
	.task_tick		= task_tick_fcfs,
};
